package com.tul.exercise.base.java8.interfaceDemo;

import com.google.common.primitives.Ints;
import com.tul.cusa.common.log.LogTracerFactory;
import com.tul.cusa.common.log.intf.ILogTracer;
import com.tul.exercise.base.java8.stream.base.Apple;
import com.tul.exercise.base.java8.stream.base.Artist;
import com.tul.exercise.base.java8.stream.optional.Person;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Objects;
import java.util.function.DoublePredicate;
import java.util.function.IntPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * Predicate接口使用示例
 *
 * @author tuliang
 */
public class PredicateTest {
    private static final ILogTracer logger = LogTracerFactory.getTracer(PredicateTest.class);

    @Test
    @DisplayName("Predicate<T>演示")
    public void test01() {

        // 使用lambda表达式
        Predicate<Integer> isLarger100 = (Integer x) -> x > 100;
        System.out.println("120 > 100:" + isLarger100.test(120));


        // 使用函数引用
        isLarger100 = Number::isLarger100;
        System.out.println("Number.n1" + isLarger100.test(125));


        // 在stream流中使用
        Predicate<Integer> isLarger100_2 = Number::isLarger100;
        List<Integer> numbers = Stream.of(123, 234, 34).collect(Collectors.toList());
        numbers.stream().forEach(n -> {
            System.out.println(isLarger100_2.test(n));
        });
        // filter()方法接受一个Predicate<T>函数接口，用于过滤元素
        List<Integer> list2 = numbers.stream().filter(Number::isLarger100).collect(Collectors.toList());
        System.out.println(list2);
    }

    @Test
    @DisplayName("Int/Long/DoublePredicate<T>演示")
    public void test02() {
        // 大于0
        IntPredicate isZero = x -> x > 0;
        IntStream.rangeClosed(-3, 3).filter(isZero).forEach(System.out::println);

        double min = 5000.0;
        double max = 10000.0;
        // 过滤出重量大于min的苹果
        DoublePredicate isHeavy = x -> x > min;
        Apple.createApples(10).stream()
                .filter(a -> isHeavy.test(a.getWeight()))
                .forEach(System.out::println);

        // 过滤出重量小于min的苹果,使用negate
        Apple.createApples(10).stream()
                .filter(a -> isHeavy.negate().test(a.getWeight()))
                .forEach(System.out::println);


        // 重量大于min 小于max
        DoublePredicate test = isHeavy.and(a -> a < max);
        Apple.createApples(10).stream()
                .filter(a -> test.test(a.getWeight()))
                .forEach(System.out::println);
    }

    /**
     * 测试类
     */
    public static class Number {
        private static int n1 = 100;

        public static Boolean isLarger100(Integer n2) {
            return n1 <= n2;
        }
    }
}
